package org.jflame.web.spring;

import org.jflame.commons.exception.BusinessException;
import org.jflame.commons.file.FileHelper;
import org.jflame.commons.file.MimeTypes;
import org.jflame.commons.model.CallResult;
import org.jflame.commons.model.Chars;
import org.jflame.commons.model.ResultEnum;
import org.jflame.commons.util.ArrayHelper;
import org.jflame.context.filemanager.FileAccessException;
import org.jflame.context.filemanager.FileManagerFactory;
import org.jflame.context.filemanager.IFileManager;
import org.jflame.web.WebFileProperties.UploadProp;
import org.jflame.web.WebFileService;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
public class SpringFileService extends WebFileService {

    public Map<String,String> uploadFile(MultipartFile[] uploadFiles, UploadProp prop) throws IOException {
        ArrayHelper.requireNonEmpty(uploadFiles, "请选择上传的文件");
        if (prop.getMaxFileSize() > 0) {
            for (MultipartFile part : uploadFiles) {
                if (prop.isSizeExceeds(part.getSize())) {
                    throw new BusinessException("文件大小超过限制,最大" + prop.maxFileSizeAsKB() + "KB", 4001);
                }
            }
        }
        Map<String,String> resultMap = new HashMap<>();
        String tmpUrl,tmpFileName;
        IFileManager fileManager = FileManagerFactory.getCurrentManager();
        for (MultipartFile uploadFile : uploadFiles) {
            tmpFileName = uploadFile.getOriginalFilename();
            // 部分浏览器可能带路径,删除路径部分
            if (tmpFileName.indexOf(Chars.SLASH) >= 0) {
                tmpFileName = FileHelper.getFilename(tmpFileName);
            }
            tmpUrl = save(uploadFile.getInputStream(), tmpFileName, prop);
            resultMap.put(uploadFile.getOriginalFilename(),
                    prop.isReturnAbsoluteUrl() ? fileManager.toRequestUrl(tmpUrl) : tmpUrl);
        }
        return resultMap;
    }

    /**
     * 保存文件,返回相对于给定保存文件夹的路径
     *
     * @param uploadFile 上传文件对象
     * @param props 上传限制属性
     * @return 返回上传后文件路径
     */
    public CallResult<String> uploadFile(MultipartFile uploadFile, UploadProp props) {
        CallResult<String> result = new CallResult<>();
        if (uploadFile == null || uploadFile.isEmpty()) {
            return result.paramerror("请选择上传的文件");
        }
        if (log.isDebugEnabled()) {
            log.debug("上传文件参数,file:{},props:{}", uploadFile.getOriginalFilename(), props);
        }

        try {
            Map<String,String> resultMap = uploadFile(new MultipartFile[] { uploadFile }, props);
            result.success(resultMap.values()
                    .iterator()
                    .next());
        } catch (BusinessException e) {
            log.error("上传文件异常,file:{}, err:{} ", uploadFile.getOriginalFilename(), e.getMessage());
            result.result(e);
        } catch (FileAccessException e) {
            log.error("上传文件异常,file:{}, err:{} ", uploadFile.getOriginalFilename(), e.getMessage());
            result.status(ResultEnum.SERVER_ERROR.getStatus())
                    .message(e.getMessage());
        } catch (IOException e) {
            log.error("上传文件异常,file:" + uploadFile.getOriginalFilename(), e);
            result.status(ResultEnum.SERVER_ERROR.getStatus())
                    .message("文件上传出现错误");
        }
        return result;
    }

    /**
     * 上传图片
     *
     * @param imgFile 图片
     * @param maxSize 图片最大尺寸 单位K
     * @param saveDir 保存文件夹
     * @return 上传后相对路径
     */
    public CallResult<String> uploadImage(MultipartFile imgFile, int maxSize, String saveDir) {
        UploadProp props = new UploadProp();
        props.setAllowTypes(MimeTypes.WEB_IMAGE_EXTENSIONS);
        if (saveDir != null) {
            props.setDir(saveDir);
        }
        if (maxSize > 0) {
            props.setMaxFileSize(maxSize);
        }
        return uploadFile(imgFile, props);
    }

}
